const log4js = require('log4js');
const crypto = require('crypto');
const fs = require('fs');
const { spawn, execFile } = require('child_process');
const nodeUtil = require('util');

const config = require('./config');

// 日志
console.log('dosc-publish module : ' + process.env.DOCS_PUBLISH_MODULE)
log4js.configure(process.env.DOCS_PUBLISH_MODULE === 'proc' ? config.log4js_conf.proc : config.log4js_conf.dev);
const logger = log4js.getLogger('app');

const errMsg = {
  '-1': '用户名或密码错误',
  '-99': '未定义的异常'
};
const USER_SIGN_KEY = 'lian.zuotai-1234';   //用户签名key

const exists = nodeUtil.promisify(fs.exists);   //目录存在
const mkdir = nodeUtil.promisify(fs.mkdir);
const rename = nodeUtil.promisify(fs.rename);

function hexMd5 (str) {
  let md5 = crypto.createHash('md5');
  md5.update(str, 'utf-8');
  return md5.digest('hex');
}

/**
 * 创建目录，并返回路径地址，args为目录层级数组
 */
const mkdirs = (path, args)=>{
  logger.debug(`create dir: ${path}`);
  if (! fs.existsSync(path)){
    fs.mkdirSync(path);
  }
  if (args && args.length){
    let dir = args.shift();
    return mkdirs(`${path}/${dir}`, args);
  }else{
    return path;
  }
};

/**
 * 将 git 命令输出的8进制数字，转为汉字
 */
const number2String = (numberString) => {
  let numberArray = numberString.split('\\')
  let numbers = []
  for (let n of numberArray) {
    n && numbers.push(parseInt(Number(n), 8))
  }
  let buf = ''
  for (let i = numbers.length - 1; i>=0; i -= 3) {
    if (i >= 2) {
      buf = Buffer.from([numbers[i-2], numbers[i-1], numbers[i]]) + buf
    }
  }
  return buf;
}

/**
 * git输出中的8进制数字转汉字
 */
const out2String = (str) => {
  let reg = /(\\[0-9]{3})+/g

  let buf = ''
  let begin = 0, end = str.length;
  let match = reg.exec(str)
  while(match){
    buf += str.substr(begin, match.index - begin)
    buf += number2String(match[0])
    begin = match.index + match[0].length
    match = reg.exec(str);
  }
  buf += str.substr(begin, end)
  return buf
}

module.exports = {
  logger, hexMd5, exists, mkdir, mkdirs, rename, out2String,
  //返回的异常对象
  getErrMsg: (key) =>{
    if (errMsg[key]){
      return {
        code: key,
        msg: errMsg[key]
      }
    }else{
      return {
        code: '-99',
        msg: errMsg['-99']
      }
    }
  },
  sucResMsg: {
    code: '0',
    msg: '成功'
  },
  parseJson: (data) => {
    if (data && data.length){
      for(let row of data){
        row.content = JSON.parse(row.content);
        row.date = new Date(row.date);
      }
    }
  },
  signUser: ({user, psw}) => {
    return hexMd5(`${user}^${psw}^${USER_SIGN_KEY}`)
  },
  runShell: (path) => {
    return new Promise((suc, fail) => {
      execFile(path, (error, stdout, stderr) => {
        if (error) {
          logger.error(`run shellscript ${path} error: `, error);
          fail(error)
        } else {
          logger.debug(`run ${path} stdout: ${stdout}`)
          logger.debug(`run ${path} stderr: ${stderr}`)
          suc({ stdout, stderr })
        }
      })

      // let out = '';

      // logger.info('run shell : %s', path);

      // const sh = spawn(path);

      // sh.stdout.on('data', (data) => {
      //   logger.info('stdout > ' + data);
      //   out += ('stdout > ' + data);
      // });

      // sh.stderr.on('data', (data) => {
      //   logger.info('stderr > ' + data);
      //   out += ('stderr > ' + data);
      // });


      // sh.on('close', (code, signal) => {
      //   logger.info('run sh over: code=%s, signal=%s', code, signal);
      //   suc(out);
      // });

      // sh.on ('error', (error) => {
      //   logger.warn('sh pull error: ', error);
      //   fail(error);
      // });

    });
  }
}


Date.prototype.format = function(formatStr)
{
    var str = formatStr;
    var Week = ['日', '一', '二', '三', '四', '五', '六'];

    str = str.replace(/yyyy|YYYY/, this.getFullYear());
    str = str.replace(/yy|YY/, (this.getYear() % 100) > 9 ? (this.getYear() % 100).toString() : '0' + (this.getYear() % 100));

    var month = this.getMonth() + 1;
    str = str.replace(/MM/, month > 9 ? month.toString() : '0' + month);
    str = str.replace(/M/g, month);

    str = str.replace(/w|W/g, Week[this.getDay()]);

    str = str.replace(/dd|DD/, this.getDate() > 9 ? this.getDate().toString() : '0' + this.getDate());
    str = str.replace(/d|D/g, this.getDate());

    str = str.replace(/hh|HH/, this.getHours() > 9 ? this.getHours().toString() : '0' + this.getHours());
    str = str.replace(/h|H/g, this.getHours());
    str = str.replace(/mm/, this.getMinutes() > 9 ? this.getMinutes().toString() : '0' + this.getMinutes());
    str = str.replace(/m/g, this.getMinutes());

    str = str.replace(/ss|SS/, this.getSeconds() > 9 ? this.getSeconds().toString() : '0' + this.getSeconds());
    str = str.replace(/s|S/g, this.getSeconds());

    return str;
};
